package com.astronomia.wheels.date_utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

/**
 * @Package com.arrail.common.utils
 * @ClassName DateUtils
 * @Author zhaozhijun
 * @Date 2018/9/11  17:05
 * @Version 1.0
 * @Description:  日期时间问题处理
 **/

@Slf4j
public class DateUtils {

    /**
     * @author zhijun.zhao
     * @date 2018/9/11 17:07
     * @param data1,data2
     * @return int
     * @Description:  日期时间之间对比
     */
    public static int compareDate(String data1, String data2) {


        DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        try {
            Date dt1 = df.parse(data1);
            Date dt2 = df.parse(data2);
            if (dt1.getTime() > dt2.getTime()) {
                return 1;
            } else if (dt1.getTime() < dt2.getTime()) {
                return -1;
            } else {
                return 0;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return 0;
    }


    /**
     * @author zhijun.zhao
     * @date 2018/9/11 17:12
     * @param
     * @return
     * @Description:  获取当前时间字符串  yyyy-MM-dd HH:mm
     */
    public static String getCurrentDateToString() {
            Date currentTime = new Date();
            SimpleDateFormat formatter = new SimpleDateFormat(DateStyle.YYYY_MM_DD_HH_MM.getValue());
            String dateString = formatter.format(currentTime);
            return dateString;
         }


    /**
     * @author zhijun.zhao
     * @date 2018/9/11 17:12
     * @param date
     * @return String
     * @Description:   时间格式转译，由data转为字符串
     */
    public static String getDateToString(Date date) {

        SimpleDateFormat formatter = new SimpleDateFormat(DateStyle.YYYY_MM_DD_HH_MM.getValue());
        String dateString = formatter.format(date);
        return dateString;
    }

     /**
      * @author zhijun.zhao
      * @date 2018/9/12 13:52
      * @param localDate
      * @return Date
      * @Description:  LocalDateTime 转Date
      */
     public static Date getLocalDateTimetoDate(LocalDateTime localDate){
             ZoneId zoneId = ZoneId.systemDefault();
             ZonedDateTime zdt = localDate.atZone(zoneId);

             return  Date.from(zdt.toInstant());
     }

     /**
      * localDate 转 Date
      * @author shaobin.wang
      * @date 2020/3/16 14:28
      */
    public static Date getLocalDatetoDate(LocalDate localDate){
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDate.atStartOfDay(zoneId);
        return  Date.from(zdt.toInstant());
    }

    /**
     * @author zhijun.zhao
     * @date 2018/9/13 19:10
     * @param date
     * @return LocalDateTime
     * @Description:  date与LocalDateTime进行转换
     */
    public static LocalDateTime getDateToLocalDateTime(Date date){
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();

        return instant.atZone(zoneId).toLocalDateTime();
    }

    /**
     * @author zhijun.zhao
     * @date 2018/10/25 10:06
     * @param
     * @return String
     * @Description:  获取当前年份
     */
    public static String getSysYear() {
        Calendar date = Calendar.getInstance();
        String year = String.valueOf(date.get(Calendar.YEAR));
        return year;
    }

    /**
     * @author zhijun.zhao
     * @date 2018/10/25 10:09
     * @param
     * @return String
     * @Description: 获取当前月份
     */
    public static String getSysMonth() {
        Calendar date = Calendar.getInstance();
        String month = String.valueOf(date.get(Calendar.MONTH) + 1);
        return month;
    }

    /**
     * @author zhijun.zhao
     * @date 2018/10/25 10:10
     * @param
     * @return String
     * @Description: 获取当前日
     */
    public static String getSysDay() {
        Calendar date = Calendar.getInstance();
        String day = String.valueOf(date.get(Calendar.DAY_OF_MONTH));
        return day;
    }

    /**
     * @param birthDay
     * @return int
     * @author liyucheng
     * @date 2018/11/7 17:03
     * @description 由出生日期获得年龄  精确到天
     */
    public static int calcAge(Date birthDay) {
        Calendar cal = Calendar.getInstance();
        if (cal.before(birthDay)) {
            throw new IllegalArgumentException("出生日期不能晚于当前日期");
        }
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH);
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
        cal.setTime(birthDay);

        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

        int age = yearNow - yearBirth;

        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;
                }
            } else {
                age--;
            }
        }
        return age;
    }
    /**
    * @param birthday
     * @return  Integer
     * @author liyucheng
     * @date 2018/12/27 11:13
     * @description  生日提醒 1提醒 2 不提醒
     */
    public static Integer birthdayTips(Date birthday) {
        LocalDateTime dateTime = getDateToLocalDateTime(birthday);
        LocalDateTime now = LocalDateTime.now();
        dateTime.getDayOfMonth();
        if(dateTime.getMonthValue() == now.getMonthValue() && now.getDayOfMonth() == dateTime.getDayOfMonth()){
            return 1;
        }
        return 0;
    }

    /**
    * @param month
     * @return Date
     * @author liyucheng
     * @date 2018/12/27 11:17
     * @description 根据传入前几个月时间 获取指定时间月份的 第一天
     */
    public static Date getStartMonth(Integer month){
        if(StringUtils.isEmpty(month)){
            return null;
        }
        Calendar date = Calendar.getInstance();
        date.add(Calendar.MONTH, -month);
        date.set(Calendar.DAY_OF_MONTH,1);
        return date.getTime();
    }

    /**
     * @return  Date
     * @author liyucheng
     * @date 2018/12/27 11:23
     * @description 获取前一个月的最后一天
     */
    public static Date getEndMonth(){
        Calendar date = Calendar.getInstance();
        date.set(Calendar.DAY_OF_MONTH, 0);
        return date.getTime();
    }
    /**
    * @param dateString
     * @return  Date
     * @author liyucheng
     * @date 2019/1/24 16:56
     * @description string转date yyyy-MM-dd hh:mm:ss
     */
    public static Date stringToDate(String dateString){
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date parse = null;
        try {
            parse = df.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return parse;
    }

    /**
     * @author zhijun.zhao
     * @date 2019/1/30 10:21
     * @param age
     * @return Date
     * @Description: 根据年龄获取出生年月
     */
    public static Date getfakeBirthday(int age){
        Date parse = null;
        //获取现在时间
        Calendar mycalendar=Calendar.getInstance();
        //获取年份
        String year =String.valueOf(mycalendar.get(Calendar.YEAR));
        int yearInt = Integer.parseInt(year);
        int birth=yearInt-age;
        String dateStr = birth+"-01-01";
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            parse = df.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return parse;
    }

    /**
     * @author zhijun.zhao
     * @date 2019/1/30 10:23
     * @param birthDay
     * @return int
     * @Description: 根据出生日志获取年龄
     */
    public static int getAge(Date birthDay){

        Calendar cal = Calendar.getInstance();
        if (cal.before(birthDay)) {
            throw new IllegalArgumentException(
                    "The birthDay is before Now.It's unbelievable!");
        }
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH);
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
        cal.setTime(birthDay);

        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

        int age = yearNow - yearBirth;

        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                if (dayOfMonthNow < dayOfMonthBirth){
                    age--;
                }
            }else{
                age--;
            }
        }
        return age;

    }

    public static Date getDate(){
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String d = df.format(new Date());
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(d, pos);
        return strtodate;
    }

    public static Date getYearDate(Date date){
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String d = df.format(date);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(d, pos);
        return strtodate;
    }

    public static String getCurrentDate(){
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        return df.format(new Date());
    }

    /**
     * @author zhijun.zhao
     * @date 2019/6/27 17:31
     * @param
     * @return
     * @Description:  判断日期是否为当天
     */
    public static boolean isToday(Date date) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        if (fmt.format(date).equals(fmt.format(new Date()))) {//格式化为相同格式
            return true;
        } else {
            return false;
        }
    }

    /**
     * 可以传字符串、数字等，需要先判断空
     * @param obj
     * @return
     */
    public static String receiptsTo(Object obj){
        //#,##0.00，解决金额小于1时金额显示格式不正确的问题；比如0.5元，#,###.00格式就会显示成.50，这显然不正确。
        BigDecimal bigDecimal = new BigDecimal(obj.toString());
        NumberFormat numberFormat = new DecimalFormat("#,##0.00");
        return numberFormat.format(bigDecimal);
    }

    public static Date initDateByDay(){
        TimeZone curTimeZone = TimeZone.getTimeZone("GMT+8");
        Calendar c = Calendar.getInstance(curTimeZone);
        c.setTime(new Date());
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return c.getTime();
    }

    public static Date initDateByMonth(){
        TimeZone curTimeZone = TimeZone.getTimeZone("GMT+8");
        Calendar c = Calendar.getInstance(curTimeZone);
        c.setTime(new Date());
        c.set(Calendar.DAY_OF_MONTH,1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return c.getTime();
    }

    public static void main(String[] args) {
        try {
            String aa = receiptsTo("5000");
            System.out.println(aa);
        } catch (Exception e){
            e.printStackTrace();
        }
    }


    /**
     * 根据开始时间和结束时间返回时间段内的时间集合
     *
     * @param beginDate
     * @param endDate
     * @return List
     */
    public static List<Map<String, Date>> getDatesBetweenTwoDate(Date beginDate, Date endDate) {
        List<Map<String, Date>> mapList = new ArrayList<>();
        try {
            DateFormat df = new SimpleDateFormat("HH:mm:ss");
            Map<String, Date> initialMap = new HashMap<>();
            Calendar cal = Calendar.getInstance();
            Calendar nextCalendar = Calendar.getInstance();

            // 使用给定的 Date 设置此 Calendar 的时间
            cal.setTime(beginDate);

            nextCalendar.setTime(cal.getTime());
            nextCalendar.add(Calendar.HOUR_OF_DAY, 1);

            initialMap.put("startTime", df.parse(df.format(beginDate)));
            initialMap.put("endTime", df.parse(df.format(nextCalendar.getTime())));
            mapList.add(initialMap);

            while (true) {
                Map<String, Date> centerMap = new HashMap<>();
                // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
                cal.add(Calendar.HOUR_OF_DAY, 1);
                // 测试此日期是否在指定日期之后
                if (endDate.after(cal.getTime())) {
                    nextCalendar.setTime(cal.getTime());
                    nextCalendar.add(Calendar.HOUR_OF_DAY, 1);
                    centerMap.put("startTime", df.parse(df.format(cal.getTime())));
                    System.out.println(df.format(nextCalendar.getTime()));
                    centerMap.put("endTime", df.parse("00:00:00".equals(df.format(nextCalendar.getTime())) ? "24:00:00" : df.format(nextCalendar.getTime())));
                    mapList.add(centerMap);
                } else {
                    break;
                }
            }
            return mapList;
        } catch (ParseException e) {
            e.printStackTrace();
            return mapList;
        }
    }

    public static Date getStaticDate(int i)  {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String orgBeginDate = "2020-06-22 08:00:00";
        String orgEndDate = "2020-06-22 20:00:00";
        if (i == 1) {
            try {
                return dateFormat.parse(orgBeginDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        } else {
            try {
                return dateFormat.parse(orgEndDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}
